package com.hgxd.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hgxd.entity.pojo.SysMenu;
import com.hgxd.entity.res.ResMenuVo;
import com.hgxd.mapper.RoleMenuMapper;
import com.hgxd.mapper.SysMenuMapper;
import com.hgxd.service.SysMenuService;
import com.hgxd.utils.MenuUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author fsd
 * @since 2023-10-18
 */
@Service("SysMenuServiceImpl")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public List<SysMenu> getTreeByUserId(Long userId) {

        List<SysMenu> list = sysMenuMapper.getTreeByUserId(userId);
        // 去重
//        ArrayList<SysMenu> sysMenus = new ArrayList<>(new HashSet<>(list));
        List<SysMenu> sysMenus = MenuUtils.removeRepeat(list);
        // 构建树形结构
        //获取父id 即目录
        List<SysMenu> parentMenuList = sysMenus.stream().filter(sysMenu -> sysMenu.getParentId() == 0).collect(Collectors.toList());

        return setTree(sysMenus, parentMenuList);
    }

    @Override
    @Transactional
    public List<ResMenuVo> getMenuByRoleId(Long roleId) {
        // 查询对应roleId对应的menuIds并剔除掉menuId!=6和7的数据
        List<Integer> menuByRoleId = sysMenuMapper.getMenuByRoleId(roleId);
        SysMenu sysMenuVo = new SysMenu();
        if (!menuByRoleId.isEmpty()){
            // 不为空就将select改为true
            sysMenuVo.setIsSelect(true);
            QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("menu_id",menuByRoleId);
            sysMenuMapper.update(sysMenuVo,queryWrapper);
        }
        // 查询全部List<SysMenu>
        List<SysMenu> allSysMenuList = sysMenuMapper.selectList(null)
                .stream().filter(menu->menu.getMenuId()!=6)
                .filter(menu->menu.getMenuId()!=7).collect(Collectors.toList());
        // 转换对应响应类  List<SysMenu> -> List<ResMenuVo>
        List<ResMenuVo> allResMenuList = allSysMenuList.stream().map(sysMenuStream -> {
            String jsonString = JSON.toJSONString(sysMenuStream);
            return JSON.parseObject(jsonString, ResMenuVo.class);
        }).collect(Collectors.toList());
        // 将 List<ResMenuVo> -> 树型结构
        // 1.查询目录
        List<ResMenuVo> parentResMenuList = allResMenuList.stream()
                .filter(resMenu -> resMenu.getParentId() == 0).collect(Collectors.toList());
        // 构建树形结构
        List<ResMenuVo> resMenuVos = setTreeForResMenuVo(allResMenuList, parentResMenuList);
        ResMenuVo resMenuVo = new ResMenuVo(-1, -2L, "全部数据",0L, "全部数据", false,resMenuVos);
        // 将select置为false
        sysMenuVo.setIsSelect(false);
        sysMenuMapper.update(sysMenuVo,null);
        List<ResMenuVo> resMenuVoList = new ArrayList<>();
        resMenuVoList.add(resMenuVo);
        return resMenuVoList;
    }


    /**
     * 把SysMenu查询出来的菜单转换为树形结构
     * @param allList
     * @param parentMenuList
     * @return
     */
    public List<SysMenu> setTree(List<SysMenu> allList, List<SysMenu> parentMenuList) {
        //遍历父节点
        for (SysMenu sysMenu : parentMenuList) {
            //找到子节点
            List<SysMenu> sonMenuList = allList.stream().filter(menu -> Objects.equals(sysMenu.getMenuId(), menu.getParentId()))
                    .collect(Collectors.toList());

            //子节点还有子节点时
            if (!sonMenuList.isEmpty()) {
                List<SysMenu> grandsonMenuList = setTree(allList, sonMenuList);
                sysMenu.setChildren(grandsonMenuList);
            }
        }
        return parentMenuList;
    }

    /**
     * 把ResMenuVo查询出来的菜单转换为树形结构
     * @param allList
     * @param parentMenuList
     * @return
     */
    private List<ResMenuVo> setTreeForResMenuVo(List<ResMenuVo> allList, List<ResMenuVo> parentMenuList) {
        //遍历父节点
        for (ResMenuVo resMenuVo : parentMenuList) {
            //找到子节点
            List<ResMenuVo> sonMenuList = allList.stream().filter(menu -> Objects.equals(resMenuVo.getMenuId(), menu.getParentId()))
                    .collect(Collectors.toList());

            //子节点还有子节点时
            if (!sonMenuList.isEmpty()) {
                List<ResMenuVo> grandsonMenuList = setTreeForResMenuVo(allList, sonMenuList);
                resMenuVo.setChildren(grandsonMenuList);
            }
        }
        return parentMenuList;
    }
}
